<?php

class CBaseController{
	
	public $_isPostBack;
	public $_page;
	 
	public function __construct(){
		$this->_isPostBack = ($_SERVER['REQUEST_METHOD']=='POST');
		$this->_page = App::$Response->_page;
	}
	
	public function invoke($action){
		if(method_exists($this, $action)){
			$this->validateMethod($action);
			$this->validateSecurity($action);
			$this->setTitlePage($action);			
			$this->setDefaultView($action);			
			$this->invokeMethod($action);
		}else{
			Debug::Write("Error 404. CBaseController:Invoke:$action ; Accion no encontrada.");
		}
	}
	
	private function validateMethod($action){
		$type = $this->_actions[$action]['Method'];
		
		if($type==null){
			Warning::Write(Warning::$LEVEL_3, 
				get_class($this)." ; $action:Method no especifica acceso (GET/POST).");
		}
		
		if(in_array($_SERVER['REQUEST_METHOD'], explode(',', $type))==false){
			Debug::Write(
				"Error 200. ".get_class($this).":$action no soporta acceso: ".$_SERVER['REQUEST_METHOD']);
		}
		
		if(method_exists($this, $action)==false){
			Debug::Write(
				"Error 100. ".get_class($this).":$action no existe funcion declarada.");
		}
		
		Log::Write(get_class($this).":$action:validateMethod - OK");
	}
	
	private function validateSecurity($action){
		
		$security = $this->_actions[$action]['Security'];
		if($security==null){
			Warning::Write(Warning::$LEVEL_3, 
				get_class($this)." ; $action:Security no especifica permisos.");
		}
		
		$access = $this->_actions[$action]['Security']['Access'];
		if($access==null){
			Warning::Write(Warning::$LEVEL_3, 
				get_class($this)." ; $action:Security no especifica acceso.");
		}else{
			if($access=='PUBLIC'){ 
				Log::Write(get_class($this).":$action:validateSecurity");
				return;
			}else{
				if($this->logOnValidate()){
					//El usuario esta firmado, validamos el perfil
					Log::Write(get_class($this).":$action:validateSecurity:LogOnValidate: True");
					
					//Incluye el flujo de para obtener usuario
					App::includeFile(APP::C_Flow, Config::$opt['security']['getuser']['path_flow']); 
					$flow = new Config::$opt['security']['getuser']['flow']();
					
					//Incluye modelo de manejo de usuario
					App::includeFile(APP::C_Model, Config::$opt['security']['getuser']['path_model']);
					$model = new Config::$opt['security']['getuser']['model']();
					$model->setIdUser($_SESSION[APP_SESSIONREF]);
					
					$flow->_in_model = $model;
					if($flow->execute()){
						App::$Response->_user = $flow->_out_model;
					}else{
						Warning::Write(Warning::$LEVEL_1,
							get_class($this)." ; $action:No se encontro un usuario valido.");
					}
					return;
				}else{
					//El usuario no esta validado se redireccion
					Log::Write(get_class($this).":$action:validateSecurity:LogOnValidate: False");
					App::$Response->redirect(
						Config::$opt['security']['login']['command'],
						Config::$opt['security']['login']['action'],
						App::$Response->_layout
					);
				}
			}
		}
	}
	
	private function setTitlePage($action){
		$title = $this->_actions[$action]['Title'];
		App::$Response->_page->title = Config::$opt['enviroment']['app_name'];
		if($title==null){
			Warning::Write(Warning::$LEVEL_3,
			get_class($this)." ; $action:Title no especifica titulo de pagina.");
		}else{
			App::$Response->_page->title = $title; 
		}
	}
	
	private function setDefaultView($action){
		App::$Response->_default_view = $this->_actions[$action]['View'];
		if(App::$Response->_default_view == null){
			Warning::Write(Warning::$LEVEL_3,
			get_class($this)." ; $action:No especifica vista predeterminada.");
		}
	}
	
	private function invokeMethod($action){
		$model = $this->mappingObject($action);
		
		$params = array();
		
		//Obtiene los parametros enviados por GET
		foreach($_GET as $name => $value){
			if(in_array($name, array('kn_ctrl', 'kn_actn', 'kn_nmly'))==false){
				$params[$name] = $value;	
			}
		}
		
		call_user_func(array($this, $action), $model, $params);
	}
	
	private function mappingObject($action){
		
		$template;
		$countItems;
		
		if($this->_actions[$action]['Model'] == null || $this->_actions[$action]['Model']['Object'] == null)
		{
			$model = new CBaseModel();	
		}else{
			
			if($this->_actions[$action]['Model']['List']){
				$count_list = (isset($_POST['kn_form_list_count']))?$_POST['kn_form_list_count']:0; 
				$list = true; //La lista es correcta
			}
			
			$template = $this->_actions[$action]['Model']['Object'];
			
			if(class_exists($template)==false){
				Debug::Write(
				"Error 100. ".get_class($this).":$action; Model:Object:$template No existe la clase o referencia.");
			}
			
			$model = new $template();
		}
		
		if($list==true){
			$list_model = array();
			//Lista carga bucle
			for($i=0;$i<=$count_list-1;$i++){
				$model = new $template();
				foreach(get_object_vars($model) as $field){
					$name_control = $field->id_control."_i$i";
					if(isset($_GET[$name_control]))
					{ $field->value = Text::Get($_GET[$name_control]); }
					if(isset($_POST[$name_control]))
					{ $field->value = Text::Get($_POST[$name_control]); }
				}
				$list_model[] = $model;
			}
			return $list_model;
		}else{
			//No es lista carga normal
			foreach(get_object_vars($model) as $field){
				if(isset($_GET[$field->id_control]))
				{ $field->value = Text::Get($_GET[$field->id_control]); }
				if(isset($_POST[$field->id_control]))
				{ $field->value = Text::Get($_POST[$field->id_control]); }
			}
			return $model;
		}
	}
	
	private function logOnValidate(){
		if(isset($_SESSION[APP_SESSIONREF])){
			if(isset($_SESSION[APP_SESSION_LAST_ACTIVITY]) == false){ return false; }
			if ( 
			(time() - $_SESSION[APP_SESSION_LAST_ACTIVITY] > Config::$opt['security']['timeout'])) {
				session_destroy();   // destroy session data in storage
				session_unset();     // unset $_SESSION variable for the runtime
				return false;
			}else{
				$_SESSION[APP_SESSION_LAST_ACTIVITY] = time(); // update last activity time stamp
				return true;
			}
		}
	}
}